package com.cskaoyan.javase.oop2._0encapsulate._0introduction;

/**
 * 封装（encapsulate）是指将数据及相关操作绑定在一起的一种编程机制，使其构成一个不可分割的独立实体。
 * 封装是面向对象语言特性的基本,在Java中，类就是这样一种结构。
 * 当然，数据被保护在类的内部，是为了尽可能地隐藏内部的细节，只保留一些对外"接口"使之与外部发生联系。
 * 之所以要封装，是为了将代码的使用者和实现者分开。使用者能够完全得到自己想要的功能，又不需要思考过多细节；实现者可以隐藏功能实现的细节，方便灵活进行修改而不影响使用者使用。
 *
 * 从实际的语法角度上来说，Java当中的封装(除了类这种结构),在类体当中是依赖于访问权限修饰符来实现：
 * 比如完全不需要被外界知道的属性，在类中完全可以私有化。
 * 如不希望被外界访问的age属性：
 * private int age;
 * 在实际开发中,如果没有特殊需求,都应该私有化类的成员变量
 * 一般来说,类中的成员变量,无脑私有化,是没有问题的
 * 当然具体情况具体分析.
 *
 * 当然私有化成员变量后,在外界就不能直接使用"对象名点"访问了
 * 在这种情况下,如果还希望外界能够访问,就需要使用 Getter/Setter 方法了。
 *
 * Getter/Setter方法的格式比较固定：
 * Getter方法提供外界访问的途径，一般命名为getXxx（Xxx是成员变量名），一般直接返回成员变量得值即可。
 * Setter方法提供外界赋值的途径，一般命名为setXxx（Xxx是成员变量名），一般使用this关键字完成赋值就可以了。
 *
 * 私有化成员变量然后提供方法访问,和直接给权限让外界访问,有什么区别?
 *      1.对象名点访问成员变量,这个访问是不可控的
 *          但是方法访问是可控的
 *      2.使用方法,将变量的"读写"区分开了
 *      3.日常开发中,即便外界有访问该成员变量的需求,也建议提供getter/setter方法来访问
 *          (因为以后变量的访问,往往涉及到框架,框架的访问依赖于getter/setter方法)
 *
 *
 * @since 11:45
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        Student s = new Student();
        // System.out.println(s.age);
        s.setAge(-1);
        System.out.println(s.getAge());
    }
}

class Student {
    private int age;

    /*
        getter用于变量的访问
        固定格式如下:
      */
    public int getAge() {
        return age;
    }

    /*
        setter用于变量的赋值
        固定格式如下:
     */
    public void setAge(int age) {
        /*
            人的年龄是有限的
            在区间[1,125]之间
            其他的赋值都是错误的,不允许赋值
         */
        if (age < 1 || age > 125) {
            System.out.println("年龄不合法!");
            return;
        }
        this.age = age;
    }
}